package br.urca.controller;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Result;
import br.urca.dao.BiCopiasDAO;
import br.urca.dao.BiCopiasEmprestadasDAO;
import br.urca.dao.BiEditorasDAO;
import br.urca.dao.BiIdiomasDAO;
import br.urca.dao.BiItensReservaDAO;
import br.urca.dao.BiMateriaisDAO;
import br.urca.dao.BiReservasDAO;
import br.urca.dao.GeCidadesDAO;
import br.urca.interceptor.InterceptResource;
import br.urca.model.BiCopias;
import br.urca.model.BiEditoras;
import br.urca.model.BiItensReserva;
import br.urca.model.BiItensReservaPK;
import br.urca.model.BiMateriais;
import br.urca.model.BiReservas;
import br.urca.session.UsuarioLogado;

@Controller
@InterceptResource
public class DetalheController  {
	
	private UsuarioLogado usuarioLogado;
	private Result result;
	private BiMateriaisDAO mBiMateriaisDAO;
	private BiEditorasDAO mEditorasDAO;
	private BiCopiasDAO mCopiasDAO;
	private BiCopiasEmprestadasDAO mCopiasEmprestadasDAO;
	private BiReservasDAO mBiReservasDAO;
	private BiItensReservaDAO mBiItensReservaDAO;
	private GeCidadesDAO mCidadesDAO;
	private BiIdiomasDAO mIdiomasDAO;
	
	@Deprecated public DetalheController() { }	
	
	@Inject
	public DetalheController(UsuarioLogado usuarioLogado, Result result,
			BiMateriaisDAO mBiMateriaisDAO, BiEditorasDAO mEditorasDAO,
			BiCopiasDAO mCopiasDAO, GeCidadesDAO mCidadesDAO,
			BiCopiasEmprestadasDAO mCopiasEmprestadasDAO, BiIdiomasDAO mIdiomasDAO, 
			BiReservasDAO mBiReservasDAO, BiItensReservaDAO mBiItensReservaDAO) {
		super();
		this.usuarioLogado = usuarioLogado;
		this.result = result;
		this.mBiMateriaisDAO = mBiMateriaisDAO;
		this.mEditorasDAO = mEditorasDAO;
		this.mCopiasDAO = mCopiasDAO;
		this.mCopiasEmprestadasDAO = mCopiasEmprestadasDAO;
		this.mBiReservasDAO = mBiReservasDAO;
		this.mBiItensReservaDAO = mBiItensReservaDAO;
		this.mCidadesDAO = mCidadesDAO;
		this.mIdiomasDAO = mIdiomasDAO;
	}

	@Path("/detalhes.livro")
	public void detalheLivro() { }
	
	@Path("/detalhes.monografia")
	public void detalheMonografia() { }
	
	@Path("/detalhes.dissertacao")
	public void detalheDissertacao() { }
	
	@Path("/detalhes.tese")
	public void detalheTese() { }
	
	@Path("/detalhes.artigo")
	public void detalheArtigo() { }
	
	@Path("/detalhes.video")
	public void detalheVideo() { }
	
	@Path("/detalhes.periodico")
	public void detalhePeriodico() { }
	
	public void reservarMaterial(Character codTipoMaterial, int codNumeroMaterial) {
		try {			
			if (codNumeroMaterial > 0 && codTipoMaterial != null) {
				List<BiReservas> listReserva = null;
				BiReservas br = new BiReservas();
				boolean reservaExiste = false;
				
				br.setData(new Date());
				if (usuarioLogado.getFuncionario() != null) {
					listReserva  = mBiReservasDAO.getListPorFuncionario(usuarioLogado.getFuncionario().getMatricula());					
					br.setMatriculaFuncionario(usuarioLogado.getFuncionario().getMatricula());		
					
				} else if (usuarioLogado.getAlunoCurso() != null) {
					listReserva  = mBiReservasDAO.getListPorAluno(usuarioLogado.getAlunoCurso().getMatricula());
					br.setMatriculaAluno(usuarioLogado.getAlunoCurso().getMatricula());
				}
				
				for (BiReservas biRes: listReserva) {
					for (BiItensReserva biItem: biRes.getBiItensReservaList()) {
						if (biItem.getBiMateriais() != null) {
							if ((biItem.getBiMateriais().getBiMateriaisPK().getCodTipoMaterial() == codTipoMaterial) &&
									(biItem.getBiMateriais().getBiMateriaisPK().getCodNumeroMaterial() == codNumeroMaterial)) {
								if (biItem.getLiberado().equals(new Character('F'))) {
									reservaExiste = true;
									break;
								}
							}
						}
					}
				}
				
				if (!reservaExiste) {
					br = mBiReservasDAO.salvar(br);								
					
					BiItensReserva item = new BiItensReserva();
					item.setBiItensReservaPK(new BiItensReservaPK(br.getCodReserva(), (short) 1));
					item.setBiMateriais(mBiMateriaisDAO.getPorTipoNumeroMaterial(codTipoMaterial, codNumeroMaterial));
					item.setLiberado(new Character('F'));
					
					if (mBiItensReservaDAO.salvar(item)) {
						result.include(
								"mensagem",
								"Reserva Nº: " + br.getCodReserva()
										+ ", criada com sucesso!").redirectTo(ReservasController.class).index();
					}
				} else {
					result.include(
							"mensagem",
							"Você já solicitou uma reserva para este item!").redirectTo(ReservasController.class).index();
				}
			}
		} catch(Exception e){ 
			result.include("mensagem", "Mensagem: ".concat(e.getMessage())).redirectTo(ReservasController.class).index();
		}
	}
	
	public void reservarPeriodico(Character codTipoMaterial, int codNumeroMaterial, String codRegistro) {
		try {			
			if (codNumeroMaterial > 0 && codTipoMaterial != null && codRegistro != null) {
				List<BiReservas> listReserva = null;
				BiReservas br = new BiReservas();
				boolean reservaExiste = false;
				
				br.setData(new Date());
				if (usuarioLogado.getFuncionario() != null) {
					listReserva  = mBiReservasDAO.getListPorFuncionario(usuarioLogado.getFuncionario().getMatricula());					
					br.setMatriculaFuncionario(usuarioLogado.getFuncionario().getMatricula());		
					
				} else if (usuarioLogado.getAlunoCurso() != null) {
					listReserva  = mBiReservasDAO.getListPorAluno(usuarioLogado.getAlunoCurso().getMatricula());
					br.setMatriculaAluno(usuarioLogado.getAlunoCurso().getMatricula());
				}
				
				for (BiReservas biRes: listReserva) {
					for (BiItensReserva biItem: biRes.getBiItensReservaList()) {
						if (biItem.getBiCopias() != null) {
							if (biItem.getBiCopias().getBiCopiasPK().getCodRegistro().equalsIgnoreCase(codRegistro)) {
								if (biItem.getLiberado().equals(new Character('F'))) {
									reservaExiste = true;
									break;
								}
							}
						}
					}
				}
				
				if (!reservaExiste) {
					br = mBiReservasDAO.salvar(br);								
					BiItensReserva item = new BiItensReserva();
					item.setBiItensReservaPK(new BiItensReservaPK(br.getCodReserva(), (short) 1));
					item.setBiCopias(new BiCopias(codTipoMaterial, codNumeroMaterial, codRegistro));
					item.setLiberado(new Character('F'));
					
					if (mBiItensReservaDAO.salvar(item)) {
						result.include(
								"mensagem",
								"Reserva Nº: " + br.getCodReserva()
										+ ", criada com sucesso!").redirectTo(ReservasController.class).index();
					}
				} else {
					result.include(
							"mensagem",
							"Você já solicitou uma reserva para este item!").redirectTo(ReservasController.class).index();
				}
			}
		} catch(Exception e){ 
			result.include("mensagem", "Mensagem: ".concat(e.getMessage())).redirectTo(ReservasController.class).index();
		}
	}

	public void exibirDetalhe(Character codTipoMaterial, int codNumeroMaterial) {
		try {
			BiMateriais material = mBiMateriaisDAO.getPorTipoNumeroMaterial(codTipoMaterial, codNumeroMaterial);
			
			if (material != null) { //Se o material existir
				
				if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("1")) { // Se for um livro				
					
					buscarDetalhesLivro(material, codTipoMaterial, codNumeroMaterial);
					
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("2")) { // Periódicos
					
					buscarDetalhesPeriodicos(material, codTipoMaterial, codNumeroMaterial);
					
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("3")) { // Monografia
					
					buscarDetalhesMonoDissertacaoTese(material, codTipoMaterial, codNumeroMaterial);
					
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("5")) { // Dissertação
					
					buscarDetalhesMonoDissertacaoTese(material, codTipoMaterial, codNumeroMaterial);
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("6")) { // Tese
					
					buscarDetalhesMonoDissertacaoTese(material, codTipoMaterial, codNumeroMaterial);
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("7")) { // Artigo
					
					buscarDetalhesMonoDissertacaoTese(material, codTipoMaterial, codNumeroMaterial);  
				} else if (String.valueOf(material.getBiMateriaisPK().getCodTipoMaterial()).equalsIgnoreCase("4")) { // Video
					
					buscarDetalhesVideo(material, codTipoMaterial, codNumeroMaterial);  
				}
			} else {
				throw new Exception("Material não encontrado");
			}
							
		} catch (Exception e) {
			result.include("mensagem", "Mensagem: ".concat(e.getMessage())).redirectTo(this).detalheLivro();
		}
	}
	
	private void buscarDetalhesPeriodicos(BiMateriais material, Character codTipoMaterial, int codNumeroMaterial) {
		
		List<BiCopias> listCopias = mCopiasDAO.getPorId(codTipoMaterial, codNumeroMaterial);
		List<String> listRegistros = new ArrayList<String>();
		BiEditoras editora = mEditorasDAO.getPorId(material.getCodEditora());
		String nomeEditora = "";
		String nomeCidade = "";
		String idioma = "";
		
		int exemplaresDisponiveis = 0;
		if (editora != null) {
			nomeEditora = editora.getNome();
		}
		
		if (material.getCodCidade() != null) {
			nomeCidade = mCidadesDAO.getCidadePorId(material.getCodCidade()).getNome();
		}
		
		if (material.getCodIdioma() != null) {
			idioma = mIdiomasDAO.getPorId(material.getCodIdioma()).getDescricao();
		}
		
		if (listCopias != null && !listCopias.isEmpty()) {
			for (int i = 0; i < listCopias.size(); i++) {				
				if (mCopiasEmprestadasDAO.getPorId(codTipoMaterial,
						codNumeroMaterial, listCopias.get(i).getBiCopiasPK()
								.getCodRegistro()) == null) {
					if (String.valueOf(listCopias.get(i).getSituacao()).equalsIgnoreCase("E")) {
						exemplaresDisponiveis++;
					}
					listCopias.get(i).setStatus("Disponível");								
				} else {
					listCopias.get(i).setStatus("Emprestado");
				}	
				listRegistros.add(listCopias.get(i).getBiCopiasPK().getCodRegistro());
			}
		}	
		
		List<BiItensReserva> listItensReservas = mBiItensReservaDAO.getItensPendentes(listRegistros);
		
		if (listItensReservas != null && !listItensReservas.isEmpty()) {
			result.include("totalReservas", listItensReservas.size());
		} else {
			result.include("totalReservas", 0);
		}
		
		//Collections.sort(listCopias, BiCopias.POR_ANO);
		
		result.include("material", material).include("listaCopias", listCopias)
				.include("cidade", nomeCidade).include("idioma", idioma)
				.include("exemplaresDisponiveis", exemplaresDisponiveis)
				.include("exemplaresExistentes", listCopias.size())
				.include("editora", nomeEditora);
		
		result.redirectTo(this).detalhePeriodico();
		
	}
	
	private void buscarDetalhesLivro(BiMateriais material, Character codTipoMaterial, int codNumeroMaterial) {
		List<BiCopias> listCopias = mCopiasDAO.getPorId(codTipoMaterial, codNumeroMaterial);
		BiEditoras editora = mEditorasDAO.getPorId(material.getCodEditora());
		String nomeEditora = "";
		
		int exemplaresDisponiveis = 0;
		
		if (editora != null) {
			nomeEditora = editora.getNome();
		}
		
		List<BiItensReserva> listItensReservas = mBiItensReservaDAO.getItensPendentes(codTipoMaterial, codNumeroMaterial);
		
		if (listItensReservas != null && !listItensReservas.isEmpty()) {
			result.include("totalReservas", listItensReservas.size());
		} else {
			result.include("totalReservas", 0);
		}
		
		if (listCopias != null && !listCopias.isEmpty()) {
			for (int i = 0; i < listCopias.size(); i++) {				
				if (mCopiasEmprestadasDAO.getPorId(codTipoMaterial,
						codNumeroMaterial, listCopias.get(i).getBiCopiasPK()
								.getCodRegistro()) == null) {
					if (String.valueOf(listCopias.get(i).getSituacao()).equalsIgnoreCase("E")) {
						exemplaresDisponiveis++;
					}
					listCopias.get(i).setStatus("Disponível");								
				} else {
					listCopias.get(i).setStatus("Emprestado");
				}				
			}
		}			
		
		result.include("material", material).include("listaCopias", listCopias)
				.include("exemplaresDisponiveis", exemplaresDisponiveis)
				.include("exemplaresExistentes", listCopias.size())
				.include("editora", nomeEditora);
		
		result.redirectTo(this).detalheLivro();
	}

	private void buscarDetalhesMonoDissertacaoTese(BiMateriais material, Character codTipoMaterial, int codNumeroMaterial) {
		
		int exemplaresDisponiveis = 0;
		List<BiCopias> listCopias = mCopiasDAO.getPorId(codTipoMaterial, codNumeroMaterial);
		List<BiItensReserva> listItensReservas = mBiItensReservaDAO.getItensPendentes(codTipoMaterial, codNumeroMaterial);
		
		if (listItensReservas != null && !listItensReservas.isEmpty()) {
			result.include("totalReservas", listItensReservas.size());
		} else {
			result.include("totalReservas", 0);
		}
		
		if (listCopias != null && !listCopias.isEmpty()) {
			for (int i = 0; i < listCopias.size(); i++) {
				if (mCopiasEmprestadasDAO.getPorId(codTipoMaterial,
						codNumeroMaterial, listCopias.get(i).getBiCopiasPK()
								.getCodRegistro()) == null) {
					listCopias.get(i).setStatus("Disponível");	
					if (String.valueOf(listCopias.get(i).getSituacao()).equalsIgnoreCase("E")) {
						exemplaresDisponiveis++;
					}
				} else {
					listCopias.get(i).setStatus("Emprestado");
				}
			}
		}
		
		result.include("material", material)
			.include("listaCopias", listCopias)
			.include("exemplaresDisponiveis", exemplaresDisponiveis)
			.include("exemplaresExistentes", listCopias.size());
		if (String.valueOf(codTipoMaterial).equalsIgnoreCase("3"))
			result.redirectTo(this).detalheMonografia();
		else if (String.valueOf(codTipoMaterial).equalsIgnoreCase("5"))
			result.redirectTo(this).detalheDissertacao();
		else if (String.valueOf(codTipoMaterial).equalsIgnoreCase("6"))
			result.redirectTo(this).detalheTese();
		else if (String.valueOf(codTipoMaterial).equalsIgnoreCase("7"))
			result.redirectTo(this).detalheArtigo();
	}
	
	private void buscarDetalhesVideo(BiMateriais material, Character codTipoMaterial, int codNumeroMaterial) {
		int exemplaresDisponiveis = 0;
		List<BiCopias> listCopias = mCopiasDAO.getPorId(codTipoMaterial, codNumeroMaterial);
		List<BiItensReserva> listItensReservas = mBiItensReservaDAO.getItensPendentes(codTipoMaterial, codNumeroMaterial);
		
		if (listItensReservas != null && !listItensReservas.isEmpty()) {
			result.include("totalReservas", listItensReservas.size());
		} else {
			result.include("totalReservas", 0);
		}
		
		if (listCopias != null && !listCopias.isEmpty()) {
			for (int i = 0; i < listCopias.size(); i++) {
				if (mCopiasEmprestadasDAO.getPorId(codTipoMaterial,
						codNumeroMaterial, listCopias.get(i).getBiCopiasPK()
								.getCodRegistro()) == null) {
					listCopias.get(i).setStatus("Disponível");	
					if (String.valueOf(listCopias.get(i).getSituacao()).equalsIgnoreCase("E")) {
						exemplaresDisponiveis++;
					}
				} else {
					listCopias.get(i).setStatus("Emprestado");
				}
			}
		}
		
		result.include("material", material)
			.include("listaCopias", listCopias)
			.include("exemplaresDisponiveis", exemplaresDisponiveis)
			.include("exemplaresExistentes", listCopias.size());
		result.redirectTo(this).detalheVideo();
	}
	
	
}
